home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / shufflc.exe / SHUFFELC.C < prev    next >
C/C++ Source or Header  |  1991-11-06  |  8KB  |  217 lines

  1. /*  permute a list of items at random and assign the top N as specified on input
  2.     actually set up for in-memory operation on poker hands with poker scoring
  3.     w.howell  CIS 70215,206   11/2/91
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <time.h>
  8.  
  9. #ifdef ANSIC
  10. #include <stdlib.h>
  11. #include <sys/timeb.h>
  12. void  main(int , char  * *);
  13. void  shsort(int  * , int  * , int);        /* sort of D.L. Shell */
  14. int   scoreit(int  * , int * );             /* score 5-card poker hand */
  15. void help(int , char * );                   /* user help & exit */
  16. #endif
  17.  
  18. #ifdef BSD43
  19. typedef int time_t;
  20. #include <sys/timeb.h>
  21. #include <ctype.h>
  22. void  main( );
  23. void  shsort( );              /* sort of D.L. Shell */
  24. int   scoreit( );             /* score 5-card poker hand */
  25. void  help( );                /* user help & exit */
  26. #endif
  27.  
  28. #define  FALSE   0
  29. #define  TRUE  ~FALSE
  30.  
  31. #define  NRINTBL  52
  32.  
  33.  
  34. char cards[NRINTBL][10] = {
  35.   "Two-HT", "Three-HT", "Four-HT", "Five-HT", "Six-HT", "Seven-HT", "Eight-HT",
  36.   "Nine-HT", "Ten-HT", "Jack-HT", "Queen-HT", "King-HT", "Ace-HT",
  37.   "Two-SP", "Three-SP", "Four-SP", "Five-SP", "Six-SP", "Seven-SP", "Eight-SP",
  38.   "Nine-SP", "Ten-SP", "Jack-SP", "Queen-SP", "King-SP", "Ace-SP",
  39.   "Two-DI", "Three-DI", "Four-DI", "Five-DI", "Six-DI", "Seven-DI", "Eight-DI",
  40.   "Nine-DI", "Ten-DI", "Jack-DI", "Queen-DI", "King-DI", "Ace-DI",
  41.   "Two-CL", "Three-CL", "Four-CL", "Five-CL", "Six-CL", "Seven-CL", "Eight-CL",
  42.   "Nine-CL", "Ten-CL", "Jack-CL", "Queen-CL", "King-CL", "Ace-CL" };
  43.  
  44. void main(argc, argv)
  45. int argc;
  46. char **argv;
  47. {
  48.     int nrsel, nrtimes, nrtbl, i, index[NRINTBL], srtkey[NRINTBL], 
  49.         score, denom[5];
  50.     char message[75];
  51.     unsigned seed;
  52.     struct timeb timestr;
  53.     time_t  *seedtime;
  54.  
  55.        /* random # seed is seconds past the hour + milliseconds*/
  56.     ftime(×tr);
  57.     seed = (unsigned) (timestr.time  % 3600 * 1000  +  timestr.millitm);
  58.     srand(seed);
  59.  
  60.        /* how many times to shuffel & print */
  61.     if(argc > 1) nrtimes = atoi(argv[1]);
  62.     else nrtimes = 1;  /* default is a single deal */
  63.     if(nrtimes == 0) help(1,argv[1]);
  64.  
  65.        /* how many to pick ? */
  66.     if(argc > 2) nrsel = atoi(argv[2]);
  67.     else nrsel = 5;  /* default is 5 card hand */
  68.     if(nrsel == 0) help(2, argv[2]);
  69.  
  70.        /* how many to pick from ? */
  71.     nrtbl =  NRINTBL;
  72.  
  73.     if(nrtbl < nrsel) {
  74.       sprintf(message,"Can Not chose %d items from %d available",
  75.         nrsel, nrtbl);
  76.       help(3, message);
  77.       }
  78.        /* load sort index table with integers 0 thru nrtbl - 1 */
  79.     for(i=0; i<nrtbl; i++) index[i] = i;
  80.  
  81.        /* shuffel & deal as many times as asked */
  82.     while(nrtimes--) {
  83.  
  84.        /* load sort key table with random integers 
  85.           NOTE: we don't re-load index -- similar to placing the dealt
  86.           cards back on the top of the deck before shuffeling again */
  87.       for(i=0; i<nrtbl; i++)  srtkey[i] = rand();
  88.  
  89.        /* now sort the table by the random numbers (ie. shuffel them) */
  90.       shsort(srtkey, index, nrtbl);
  91.  
  92.        /* now score the hand of 5 cards */
  93.       if(nrsel == 5) {
  94.         score = scoreit(index, denom);   printf("%d : ", score);
  95.         }
  96.        /* then simply print out the first nrsel items -- WHAT A deal??? */
  97.       for(i=0; i<nrsel; i++) printf("%s ", cards[index[i]]);
  98.       printf("\n");
  99.       }
  100. }
  101. void shsort(key, bag, nelem)           /* shell sort of key -- rearrange bag */
  102. int  *key, nelem;               /* integer key table contains nelem elements */
  103. int  *bag;     /* bag is a pointer table to baggage which must be rearranged */
  104. {
  105.  
  106. /* sort key table of nelem integers and re-arrange bag via method of D.L. Shell
  107.    "A High Speed Sorting Proceedure" comm. acm 2 (july 1959), 30-32
  108.     -- w.howell 1/1/90 */
  109.  
  110.     int i, *ipt,*ibpt, j,*jpt,*jbpt,k, *lpt,*lbpt, m, t, nel, flag;
  111.  
  112.       /* skip rearrangement of bag if nelem is negative */
  113.     if(nelem < 0) { flag = FALSE; nel = - nelem; }
  114.     else          { flag = TRUE;  nel = nelem; }
  115.  
  116.     m = nel;
  117.     while( (m = m / 2) > 0) {
  118.       k = nel - m;
  119.  
  120.       for(j = 0, jpt = key, jbpt = bag; j < k; j++, jpt++, jbpt++) {
  121.         i   = j;
  122.         ipt = jpt;  lpt = ipt + m;
  123.         ibpt = jbpt;  lbpt = ibpt + m;
  124.         while(i >= 0) {
  125.           if(*ipt <= *lpt) break;
  126.           t = *ipt;    *ipt = *lpt;     *lpt = t;
  127.           if(flag) { t = *ibpt;   *ibpt = *lbpt;   *lbpt = t; }
  128.           i = i - m;
  129.           lpt = ipt; ipt = ipt - m;
  130.           lbpt = ibpt; ibpt = ibpt - m;
  131.           }
  132.         }
  133.  
  134.       }
  135. }
  136. /* score the poker hand of 5 cards stored in ind -- return 0-9 score PLUS
  137.      sorted demonation list in value list (in case of tied scores) */
  138. int scoreit(ind, valist)
  139. int *ind, *valist;
  140. {
  141.     int  i, suit, value, nsuit[4], nvalue[13], imin, imax,
  142.       flush = FALSE, strght = TRUE,  n_two_of = 0,
  143.       three_of = FALSE, four_of = FALSE;
  144.  
  145.     for(i=0; i<4; i++) nsuit[i] = 0;
  146.     for(i=0; i<13; i++) nvalue[i] = 0;
  147.  
  148.     for(i=0; i<5; i++) {
  149.       suit = ind[i] / 13;  value = ind[i] % 13;
  150.       valist[i] = value;
  151.       nsuit[suit]++;  nvalue[value]++;
  152.       }
  153.  
  154.       /* straight */
  155.     shsort(valist, valist, -5);
  156.       /* wrap ace in front of duce ?? */
  157.     if(valist[0] == 0 && valist[4] == 12)  imax = 4;
  158.     else  imax = 5;
  159.     for(i=1; i<imax; i++) {
  160.       if( (valist[i] - valist[i-1]) != 1) strght = FALSE;
  161.       }
  162.  
  163.       /* flush */
  164.     for(suit=0; suit < 4; suit++) {
  165.       if(nsuit[suit] == 5) flush = TRUE;
  166.       }
  167.  
  168.       /* X_of_a_kind */
  169.     for(value=0; value < 13; value++) {
  170.       switch(nvalue[value]) {
  171.         case(2):  n_two_of++;       break;
  172.         case(3):  three_of = TRUE;  break;
  173.         case(4):  four_of  = TRUE;  break;
  174.         default:  break;
  175.         }
  176.       }
  177.       /* now decide score */
  178.       /* Using Hoyle's Games pg. 100 table here -- no logic to break down
  179.          ties between two hands which score the same, but sorted hand VALUES
  180.          are returned in valist. */
  181.     if(flush && strght) {  /* did we get a ROYAL ??? */
  182.       if(valist[0] == 8 && valist[4] == 12) return 9;    /* WOW!! ROYAL FLUSH */
  183.       else return 8;                             /* NOT BAD -- straight flush */
  184.       }
  185.     if(four_of) return 7;                                      /* 4 of a kind */
  186.     if(three_of && n_two_of == 1) return 6;                     /* FULL HOUSE */
  187.     if(flush) return 5;                                       /* normal flush */
  188.     if(strght) return 4;                                   /* normal straignt */
  189.     if(three_of) return 3;
  190.     if(n_two_of == 2) return 2;
  191.     if(n_two_of == 1) return 1;
  192.     return 0;
  193. void help(helpno, helptext)
  194. int helpno;
  195. char *helptext;
  196. {
  197.  switch(helpno) {
  198.     case(1):
  199.     case(2):
  200.       fprintf(stderr,"Bad command-line argument %s\n", helptext);
  201.       break;
  202.     case(3):
  203.       fprintf(stderr,"%s\n", helptext);
  204.     default: break;
  205.     }
  206.  fprintf(stderr,"USAGE:  shuffelc  [no_times  [hand_size] ]\n");
  207.  fprintf(stderr,"     Shuffels a 52 card deck and deals a hand of size\n");
  208.  fprintf(stderr,"     hand_size (default is 5).  Shuffel & deal is repeated\n");
  209.  fprintf(stderr,"     no_times times (default is 1).\n");
  210.  fprintf(stderr," EXAMPLE: shuffelc\n");
  211.  fprintf(stderr,"  might give 3 : King-SP Four-CL Four-DI Eight-DI Four-HT\n");
  212.  fprintf(stderr,"     where 3-Fours rank #3 on Hoyle's scale of 0 (nothing)\n");
  213.  fprintf(stderr,"     to 9 (Royal Flush).\n");
  214.  exit(4);
  215. }
  216.